{$CLEO .qa}
{$USE CLEO+}
{$USE newOpcodes}
{$USE ini}

0000: NOP

script_name "HmPeds"

// By ArtemQa146

// 0@ ped - 10@ render

const
    Peds_Find = 29@
    Ped_Skin = 1@
    Ped_Select = 28@
    Bit_sets = 31@
    Select_Hand = 1
    Number_Peds = 4
    Progress = 30@
    iBuffer = 26@
    Pause_Time = 400
    Pause = 1000
end

0085: iBuffer = 0@ // (int)
0@ = -1

while true
wait 100
if
    Player.Defined($PLAYER_CHAR)
then
gosub @Ped_20
gosub @Realese_animation
    if
        not $ACTIVE_INTERIOR == 0
    then
        gosub @References_remove
        continue
    end

    if
        856D: not actor 0@ defined
    then
    Peds_Find = 0
    while 0EA7: get_any_char_no_save_recursive Peds_Find progress_to Peds_Find char_to 0@
    4@ = 10.0
        080E: get_actor 0@ ped_event_to 1@
        if and
            not 1@ == 9 // ped damaged
            80DF: not actor 0@ driving
            not is_char_script_controlled 0@
            not locate_char_distance_to_char 0@ char $PLAYER_ACTOR radius 4@
            locate_char_distance_to_char 0@ char $PLAYER_ACTOR radius 60.0
        then
            0470: 3@ = actor 0@ current_weapon
            0EFF: get_char_simplest_active_task 0@ id_to 1@ pointer_to 2@
            if and
                3@ == 0 //unarmed
                1@ == 900 //walk
                not Actor.Animation(0@) == "sprint_panic"
                not Actor.Animation(0@) == "woman_runpanic"
                not Actor.Animation(0@) == "idle_chat"
            then
                gosub @Ped_skin
                    if
                        Ped_Skin == true
                    then
                        gosub @Load_animation
                        if
                            056D: actor 0@ defined
                        then
                            if
                                not is_char_script_controlled 0@
                            then
                                0E0B: mark_char_as_needed 0@
                                Progress = 0

                                    if and
                                        locate_char_distance_to_char 0@ char $PLAYER_ACTOR radius 20.0
                                        02CB:   actor 0@ bounding_sphere_visible
                                    then
                                        Ped_Select = 3
                                        gosub @Animations
                                        gosub @Ped_Animations
                                        break
                                    end

                                    0209: Ped_Select = random_int_in_ranges 1 3

                                    if and
                                        not locate_char_distance_to_char 0@ char $PLAYER_ACTOR radius 35.0
                                        Ped_Select == 1
                                    then
                                        gosub @Smoke
                                        gosub @Ped_Smoke
                                        wait Pause
                                        break
                                    end

                                    if and
                                        not locate_char_distance_to_char 0@ char $PLAYER_ACTOR radius 35.0
                                        Ped_Select == 2
                                    then
                                        0209: 2@ = random_int_in_ranges 1 3 // random hand
                                        if 2@ == 1
                                        then 08BD: set Bit_sets bit Select_Hand
                                        else 08C3: clear Bit_sets bit Select_Hand
                                        end
                                        
                                        gosub @Drink
                                        gosub @Ped_Drink
                                        wait Pause
                                        break
                                    end

                                end
                            end
                        end
                    end
                end
            end
        end
    end
end


//  ,   

:Animations
0209: 2@ = random_int_in_ranges 1 6
if 2@ == 1
then 0AD3: 15@v = string_format "Homeless"
else 0AD3: 15@v = string_format "Homeless%d" 2@
end
return

:Smoke
2@ = 58
2@ *= 4
read_struct_offset 1@ iBuffer offset 2@ size 4   // Read ID of Model 2
4@ = 0.04
5@ = 0.1
6@ = 0.05
8@ = 1.0
return

:drink
1@ = 1486
4@ = 0.08
5@ = 0.02
6@ = 0.05
7@ = 180.0
8@ = 0.8
return

//  

:Ped_Animations
if or
    2@ == 3
    2@ == 4
then 0605: actor 0@ perform_animation 15@v IFP "PedEventsMod" framedelta 2.0 loop 0 lockX 0 lockY 0 lockF 0 time -1
else 0A1A: actor 0@ perform_walk_animation 15@v IFP "PedEventsMod" framedelta 2.0 loopA 0 lockX 0 lockY 0 lockF 0 -1 ms // versionC
end
wait 500
0006: TIMERB = 0
return

:Ped_Smoke
if
    not 21@ == -1
then
    0650: destroy_particle 21@
    21@ = -1
end
0F02:  0@ special_model 1@ bone 24 offset 4@ 5@ 6@ rotation 0 0 0 scale 10@ // bone 34 left hand, 24 right hand, 9 had, 3 tors
set_render_object_scale 10@ 8@ 8@ 8@
0E30: set_render_object_auto_hide 10@ dead 1 weapon 1 car 1
0A1A: actor 0@ perform_walk_animation "WalkSmoke" IFP "PedEventsMod" framedelta 2.0 loopA 0 lockX 0 lockY 0 lockF 0 -1 ms // versionC
0669: 21@ = create_attached_particle "EXHALE" on_actor 0@ with_offset 0.0 0.0 0.0 flag 1
0883: attach_particle 21@ to_actor 0@ mode 26
064C: make_particle 21@ visible
wait 500
0006: TIMERA = 0
0006: TIMERB = 0
return

:Ped_Drink
model.Load(1@)
if
    not model.Available(1@)
then
    repeat
    wait 0
    model.Load(1@)
    until model.Available(1@)
end
038B: load_requested_models
if
    08B7:   test Bit_sets bit Select_Hand
then
    7@ = 0.0
    2@ = 24
else
    2@ = 34
end

if
    056D:   actor 0@ defined
then
    0E2E: create_render_object_to_char_bone 0@ model 1@ bone 2@ offset 4@ 5@ 6@ rotation 0 7@ 0 store_to 10@
    set_render_object_scale 10@ 8@ 8@ 8@
    0E30: set_render_object_auto_hide 10@ dead 1 weapon 1 car 1
    0006: TIMERA = 0
end
model.Destroy(1@)
return

//   


:Ped_20
wait 10
    if
        056D: actor 0@ defined
    then
        0A96: 3@ = ped 0@ struct
        0D4E: 2@ = read_struct 3@ offset 0x470 size 1
        if 08B7:   test 2@ bit 3 //      
        then
            08C3: clear 2@ bit 3
            0E28: write_struct 3@ offset 0x470 size 1 value 2@ //      
            10@ = -1
            gosub @PedsMod_Delete_Render
            return
        end
        if and
            not actor.Dead(0@)
            is_char_script_controlled 0@
            locate_char_distance_to_char 0@ char $PLAYER_ACTOR radius 120.0
        then
        
            // 
            if
                Ped_Select == 1
            then
                if
                    0019:   TIMERA > 50
                then
                    0EC0: add_fx_system_particle 21@ coord 0 0 0 vel 0 0 0 size 0.6 brightness 0 rgba 1.0 1.0 1.0 0.5 lastFactor 0.3
                    0006: TIMERA = 0
                end
                0EFF: get_char_simplest_active_task 0@ id_to 3@ pointer_to 2@
                if and
                    02CB:   actor 0@ bounding_sphere_visible
                    0019:   TIMERB > 20000
                    3@ == 900
                    not 3@ == 401
                    not Actor.Animation(0@) == "WalkSmoke"
                then
                    0A1A: actor 0@ perform_walk_animation "WalkSmoke" IFP "PedEventsMod" framedelta 2.0 loopA 0 lockX 0 lockY 0 lockF 0 -1 ms // versionC
                    0006: TIMERB = 0
                    Progress += 1
                end
                if and
                    Progress >= 5
                    0019:   TIMERB > 5000
                then
                    gosub @PedsMod_Delete_Render
                    return
                end
                0D59: get_current_weather_to 2@
                if or
                    2@ == 8 // weather rain
                    2@ == 16 // weather rain 2
                then
                    gosub @PedsMod_Delete_Render
                    return
                end
            end

            // 
            if
                Ped_Select == 2
            then
                0EFF: get_char_simplest_active_task 0@ id_to 3@ pointer_to 2@
                if and
                    02CB:   actor 0@ bounding_sphere_visible
                    3@ == 900
                    0019:   TIMERA > 15000
                then
                    if
                        08B7:   test Bit_sets bit Select_Hand
                    then
                        0A1A: actor 0@ perform_walk_animation "DRNKBR_PRTL" IFP "GANGS" framedelta 4.0 loopA 0 lockX 0 lockY 0 lockF 0 -1 ms // versionC
                        0006: TIMERA = 0
                        Progress += 1
                    else
                        0A1A: actor 0@ perform_walk_animation "vend_drink2_p" IFP "vending" framedelta 4.0 loopA 0 lockX 0 lockY 0 lockF 0 -1 ms // versionC
                        0006: TIMERA = 0
                        Progress += 1
                    end
                end
                if and
                    timerb > 3000
                    Progress >= 5
                then
                    gosub @PedsMod_Delete_Render
                    return
                end
            end

            // 
            if
                Ped_Select == 3
            then
                if
                    0019:   TIMERB > 20000
                then
                    gosub @PedsMod_Delete_Render
                    return
                end
            end

            080E: get_actor 0@ ped_event_to 1@
            if or
                1@ == 49 // shoot close ped
                0E47: is_char_fighting 0@
                actor.Driving(0@)
                82D8:   not actor 0@ current_weapon == 0
            then
                gosub @PedsMod_Delete_Render
            end
        else
            gosub @PedsMod_Delete_Render
        end
    end
return


//      
:PedsMod_Delete_Render
if
    056D: actor 0@ defined
then
    if
        not locate_char_distance_to_char 0@ char $PLAYER_ACTOR radius 50.0
    then
        if
            0E0A: is_char_script_controlled 0@
        then
            01C2: remove_references_to_actor 0@ // Like turning an actor into a random pedestrian
        end
    else
        if
            Ped_Select == 1
        then
            0650: destroy_particle 21@
            21@ = -1
        end
        if
            0E0A: is_char_script_controlled 0@
        then
            if
                not 10@ <= -1
            then
                0E31: set_render_object_visible 10@ 0
            end
            if
                not actor.Dead(0@)
            then
                0E97: clear_char_secondary_tasks 0@
            end
            01C2: remove_references_to_actor 0@ // Like turning an actor into a random pedestrian
        end
    end
end
0@ = -1
10@ = -1
return

//  
:Load_animation
if or
    84EE: not animation "PedEventsMod" loaded
    84EE: not animation "VENDING" loaded
    84EE: not animation "GANGS" loaded
then
    repeat
    wait 0
    04ED: load_animation  "PedEventsMod"
    04ED: load_animation  "VENDING"
    04ED: load_animation  "GANGS"
        if and
            04EE: animation "PedEventsMod" loaded
            04EE: animation "VENDING" loaded
            04EE: animation "GANGS" loaded
        then
            break
        end
    until not player.Defined(0)
end
return


:Ped_skin
Ped_skin = false
if or
    02F2:   actor 0@ model == 77 // homeless
    02F2:   actor 0@ model == 78 // homeless
    02F2:   actor 0@ model == 79 // homeless
    02F2:   actor 0@ model == 134 // homeless
    02F2:   actor 0@ model == 135 // homeless
    02F2:   actor 0@ model == 137 // homeless
    02F2:   actor 0@ model == 212 // homeless
then
    Ped_skin = true
end
if or
    02F2:   actor 0@ model == 230 // homeless
    02F2:   actor 0@ model == 239 // homeless
then
    Ped_skin = true
end
return


//     
:References_remove
    if
        056D:   actor 0@ defined
    then
        01C2: remove_references_to_actor 0@ // Like turning an actor into a random pedestrian
        0@ = -1
        10@ = -1
    end
    if
        not 21@ == -1
    then
        0650: destroy_particle 21@
        21@ = -1
    end
return

//      ,   
:Realese_animation
if
    856D: not actor 0@ defined
then
    if and
        04EE: animation "PedEventsMod" loaded
        04EE: animation "VENDING" loaded
        04EE: animation "GANGS" loaded
    then
        04EF: release_animation "PedEventsMod"
        04EF: release_animation "GANGS"
        04EF: release_animation "VENDING"
    end
    if
        not $ACTIVE_INTERIOR == 0
    then
        0A93: terminate_this_custom_script
    end
end
return
